#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "schematic_types.h"
#include "drc_core.h"

namespace py = pybind11;

PYBIND11_MODULE(drc_core_python, m) {
    m.doc() = "DRC System Core Module";

    // 创建子模块
    py::module_ schematic_module = m.def_submodule("schematic", "Schematic module");

    // 在schematic子模块中绑定类型
    py::class_<schematic::Point>(schematic_module, "Point")
        .def(py::init<>())
        .def_readwrite("x", &schematic::Point::x)
        .def_readwrite("y", &schematic::Point::y);

    py::class_<schematic::Pin>(schematic_module, "Pin")
        .def(py::init<>())
        .def_readwrite("name", &schematic::Pin::name)
        .def_readwrite("position", &schematic::Pin::position)
        .def_readwrite("type", &schematic::Pin::type)
        .def_readwrite("net_name", &schematic::Pin::net_name);

    py::class_<schematic::Component>(schematic_module, "Component")
        .def(py::init<>())
        .def(py::init([](const py::dict& d) {
            auto comp = schematic::Component();
            if (d.contains("name"))
                comp.name = d["name"].cast<std::string>();
            if (d.contains("type"))
                comp.type = d["type"].cast<std::string>();
            return comp;
        }))
        .def_readwrite("name", &schematic::Component::name)
        .def_readwrite("type", &schematic::Component::type)
        .def_readwrite("position", &schematic::Component::position)
        .def_readwrite("pins", &schematic::Component::pins)
        .def_readwrite("properties", &schematic::Component::properties);

    py::class_<schematic::Net>(schematic_module, "Net")
        .def(py::init<>())
        .def(py::init([](const py::dict& d) {
            auto net = schematic::Net();
            if (d.contains("name"))
                net.name = d["name"].cast<std::string>();
            if (d.contains("net_type"))
                net.net_type = d["net_type"].cast<std::string>();
            return net;
        }))
        .def_readwrite("name", &schematic::Net::name)
        .def_readwrite("connected_pins", &schematic::Net::connected_pins)
        .def_readwrite("net_type", &schematic::Net::net_type);

    py::class_<schematic::Schematic>(schematic_module, "Schematic")
        .def(py::init<>())
        .def(py::init([](const py::dict& d) {
            auto sch = schematic::Schematic();
            if (d.contains("name"))
                sch.name = d["name"].cast<std::string>();
            return sch;
        }))
        .def_readwrite("name", &schematic::Schematic::name)
        .def_readwrite("components", &schematic::Schematic::components)
        .def_readwrite("nets", &schematic::Schematic::nets)
        .def("__repr__",
            [](const schematic::Schematic &s) {
                return "Schematic(name='" + s.name + "')";
            }
        );

    // 在主模块中绑定DRC相关类型
    py::class_<drc::DRCViolation>(m, "DRCViolation")
        .def(py::init<>())
        .def(py::init([](const py::dict& d) {
            auto v = drc::DRCViolation();
            if (d.contains("message"))
                v.message = d["message"].cast<std::string>();
            if (d.contains("severity"))
                v.severity = d["severity"].cast<std::string>();
            if (d.contains("component"))
                v.component = d["component"].cast<schematic::Component>();
            if (d.contains("net"))
                v.net = d["net"].cast<schematic::Net>();
            return v;
        }))
        .def_readwrite("rule_name", &drc::DRCViolation::rule_name)
        .def_readwrite("message", &drc::DRCViolation::message)
        .def_readwrite("severity", &drc::DRCViolation::severity)
        .def_readwrite("component", &drc::DRCViolation::component)
        .def_readwrite("net", &drc::DRCViolation::net)
        .def("__repr__",
            [](const drc::DRCViolation &v) {
                return "DRCViolation(severity='" + v.severity + "', message='" + v.message + "')";
            }
        );

    py::class_<drc::DRCManager>(m, "DRCManager")
        .def(py::init<>())
        .def("load_rule", &drc::DRCManager::load_rule)
        .def("load_rules_from_directory", &drc::DRCManager::load_rules_from_directory)
        .def("run_all_checks", [](drc::DRCManager& self, const schematic::Schematic& schematic) {
            py::gil_scoped_release release;  // 释放GIL
            return self.run_all_checks(schematic);
        })
        .def("run_rule", [](drc::DRCManager& self, const std::string& rule_name, const schematic::Schematic& schematic) {
            py::gil_scoped_release release;  // 释放GIL
            return self.run_rule(rule_name, schematic);
        });
} 